package service

import (
	"errors"
	"fmt"
	"gin-luban-server/global"
	"gin-luban-server/model"
	"gin-luban-server/model/request"
	"github.com/360EntSecGroup-Skylar/excelize/v2"
	"gorm.io/gorm"
	"reflect"
)

//@author: guo
//@function: CreateCmdbServers
//@description: 创建CmdbServers记录
//@param: cmdbServers model.CmdbServers
//@return: err error
func CreateCmdbServers(cmdbServers model.CmdbServer) (err error) {
	if !errors.Is(global.GVA_DB.Where("virtual_code =  ? OR ip_address = ? ", cmdbServers.VirtualCode,cmdbServers.Ipaddress).First(&model.CmdbServer{}).Error, gorm.ErrRecordNotFound) {
		return errors.New("存在相同服务器")
	}
	cmdbServers.Status = "0"
	err = global.GVA_DB.Create(&cmdbServers).Error
	return err
}



//@author: guo
//@function: UpdateCmdbServers
//@description: 更新CmdbServers记录
//@param: cmdbServers *model.CmdbServers
//@return: err error

func UpdateCmdbServers(cmdbServers model.CmdbServer) (err error) {
	var total int64
	var server []model.CmdbServer
	err = global.GVA_DB.Where("virtual_code = ? AND id != ?",cmdbServers.VirtualCode,cmdbServers.ID).Find(&server).Count(&total).Error
	if total >= 1 {
		return errors.New("存在相同服务器名称")
	}
	// 通过唯一ID进行更新
	err = global.GVA_DB.Where("id = ?", cmdbServers.ID).First(&model.CmdbServer{}).Updates(&cmdbServers).Error
	return err
}

//@author: guo
//@function: UpdateCmdbServersByIdAndStatus
//@description: 更新CmdbServers记录
//@param: cmdbServers *model.CmdbServers
//@return: err error

func UpdateCmdbServersByIdAndStatus(id int,status string) (err error) {
	var server model.CmdbServer
	err = global.GVA_DB.Where("id = ?", id).First(&server).Error
	server.Status = status
	err = global.GVA_DB.Where("id = ?", id).Updates(server).Error
	return err
}
//@author: guo
//@function: GetCmdbServers
//@description: 根据id获取CmdbServers记录
//@param: id uint
//@return: err error, cmdbServers model.CmdbServers

func GetCmdbServer(id uint) (err error, cmdbServers model.CmdbServer) {
	err = global.GVA_DB.Where("id = ?", id).First(&cmdbServers).Error
	return
}

//@author: guo
//@function: DeleteCmdbServer
//@description: 删除CmdbServers
//@param: id uint
//@return: err error, cmdbServers model.CmdbServers
func DeleteCmdbServer(cmdbServers model.CmdbServer) (err error) {
	err = global.GVA_DB.Delete(&cmdbServers).Error
	return err
}

//@author: heyibo
//@function: GetServersByProjectsList
//@description: 分页获取CmdbServers记录
//@param: info request.CmdbServersByProjectsSearch
//@return: err error, list interface{}, total int64
func GetCmdbServersByProjectsList(info request.CmdbServersByProjectsSearch) (err error, list interface{}, total int64) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	var List []model.CmdbServer
	// 如果有条件搜索 下方会自动创建搜索语句
	if len(info.ProjectCasbinInfos) > 0 {
		//var projectArray []string
		var itemTotal int64
		for _, v :=range info.ProjectCasbinInfos {
			// 创建db
			db := global.GVA_DB.Model(&model.CmdbServer{})
			var listTemp []model.CmdbServer
			fmt.Println("---------", v.ProjectCode)
			db = db.Where("project_code LIKE ? AND status = ?","%"+v.ProjectCode+"%","1")
			err = db.Count(&itemTotal).Error
			if err != nil {
				return err,List, total
			} else {
				db = db.Limit(limit).Offset(offset)
				err = db.Preload("Project").Preload("Company").Find(&listTemp).Error
			}

			total = total + itemTotal
			List = append(List,listTemp...)
		}

	}
	return err, List, total
}
//@author: guo
//@function: GetCmdbServersInfoList
//@description: 分页获取CmdbServers记录
//@param: info request.CmdbServersSearch
//@return: err error, list interface{}, total int64
func GetCmdbServersInfoList(cmdbs model.CmdbServer,info request.PageInfo,desc bool) (err error, list interface{}, total int64) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	// 创建db
	db := global.GVA_DB.Model(&model.CmdbServer{})
	var cmdbServerss []model.CmdbServer
	// 如果有条件搜索 下方会自动创建搜索语句
	if cmdbs.VirtualName != "" {
	db = db.Where("virtual_name = ?",cmdbs.VirtualName)
	}
	if cmdbs.Ipaddress != "" {
	db = db.Where("ip_address LIKE ?","%"+ cmdbs.Ipaddress+"%")
	}
	if cmdbs.EnvName != "" {
	db = db.Where("env_name = ?",cmdbs.EnvName)
	}
	// 机房
	if cmdbs.ServerIdc != "" {
		db = db.Where("server_idc = ?",cmdbs.ServerIdc)
	}

	if cmdbs.ProjectCode !="" {
		db = db.Where("project_code LIKE ?","%"+cmdbs.ProjectCode+"%")
	}
	if cmdbs.Status != "" {
		db = db.Where("status = ?",cmdbs.Status)
	}


	err = db.Count(&total).Error

	if err != nil {
		return err,cmdbServerss, total
	} else {
		db = db.Limit(limit).Offset(offset)
		err = db.Preload("Project").Preload("Company").Find(&cmdbServerss).Error
		//err = db.Preload("Company").Find(&cmdbServerss).Error
	}
	return err, cmdbServerss, total
}

//@author:
//@function: ParseServerInfoList2Excel
//@description: 导出数据
//@param: atabase model.CMDBSERVER, filePath string
//@return: err error
func ParsesServerInfoList2Excel(serverecl model.CmdbServer, filePath string) error {
	db := global.GVA_DB.Model(&model.CmdbServer{})
	var serverList []model.CmdbServer
	if serverecl.VirtualName != "" {
		db.Where("virtual_name = ?",serverecl.VirtualName)
	}

	if serverecl.Ipaddress != "" {
		db = db.Where("ip_address LIKE ?", "%"+serverecl.Ipaddress+"%")
	}

	if serverecl.EnvName != "" {
		db = db.Where("env_name = ?",serverecl.EnvName)
	}

	err := db.Preload("Project").Preload("Company").Find(&serverList).Error
	if err != nil {
		return err
	}
	// 写入 excel文件
	excel := excelize.NewFile()
	excel.SetSheetRow("Sheet1","A1",&[]string{"ID", "虚拟机code", "虚拟主机名",
		"ip地址", "端口", "用户", "密码", "系统类型", "系统版本","cpu核数","内存", "磁盘", "环境名","项目","公司", "状态"})

	for i, Form := range serverList {
		axis := fmt.Sprintf("A%d",i+2)
		excel.SetSheetRow("Sheet1",axis,&[]interface{}{
			Form.ID,
			Form.VirtualCode,
			Form.VirtualName,
			Form.Ipaddress,
			Form.Port,
			Form.User,
			Form.Password,
			Form.OsType,
			Form.OsSystem,
			Form.CpuNum,
			Form.MemInfo,
			Form.DiskSpace,
			Form.EnvName,
			Form.ProjectCode,
			Form.Company.CompanyName,
			Form.Status,
			// 要转成字符串 写入excel
		})
	}
	excel.SaveAs(filePath)
	return nil
}
//@author:
//@function: Duplicate
//@description: list的重复元素
//@param: interface{}
//@return: list

func Duplicate(a interface{}) (ret []interface{}) {
	va := reflect.ValueOf(a)
	for i := 0; i < va.Len(); i++ {
		if i > 0 && reflect.DeepEqual(va.Index(i-1).Interface(), va.Index(i).Interface()) {
			continue
		}
		ret = append(ret, va.Index(i).Interface())
	}
	return ret
}